package com.rental.houses.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rental.common.constant.RedisConstant;
import com.rental.common.result.AjaxResult;
import com.rental.model.entity.house.RentalHourse;
import com.rental.houses.mapper.RentalHourseMapper;
import com.rental.houses.service.IRentalHourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rental.model.form.hourse.InsertRentalHourseForm;
import com.rental.model.form.hourse.RentalHourseForm;
import com.rental.model.vo.PageVo;
import com.rental.model.vo.house.HouseTypeVo;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2025-01-16
 */
@Service
public class RentalHourseServiceImpl extends ServiceImpl<RentalHourseMapper, RentalHourse> implements IRentalHourseService {

    @Autowired
    private RentalHourseMapper rentalHourseMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 获取房屋列表
     * @return
     */
    @Override
    public AjaxResult<List<RentalHourse>> getRentalHourseList() {
        List<RentalHourse> list = this.list();
        redisTemplate.opsForValue().set("rentalHourseList",list);
        return AjaxResult.success(list);
    }

    /**
     * 根据查询条件获取房屋列表
     * @param rentalHourseForm
     * @return
     */
    @Override
    public AjaxResult<PageVo<RentalHourse>> getRentalHourseListBySearch(RentalHourseForm rentalHourseForm) {
        // 查询条件
        LambdaQueryWrapper<RentalHourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(RentalHourse::getLocation,rentalHourseForm.getName());
        // 分页
        Page<RentalHourse> rentalHoursePage = new Page<>(rentalHourseForm.getPage(), rentalHourseForm.getLimit());
        // 查询
        this.page(rentalHoursePage, wrapper);
        // 封装返回数据
        PageVo<RentalHourse> rentalHoursePageVo = new PageVo<>(rentalHoursePage.getRecords(), rentalHoursePage.getPages(), rentalHoursePage.getTotal());
        return AjaxResult.success(rentalHoursePageVo);
    }

    /**
     * 房屋详情
     * @param id,uid
     * @return
     */
    @Override
    public AjaxResult<RentalHourse> getRentalHourseDetail(Long id,Long uid) {
        RentalHourse rentalHourse = this.getById(id);
        rentalHourse.setViewCount(rentalHourse.getViewCount()+1);
        redisTemplate.opsForZSet().add(RedisConstant.USER_VISIT_HISTORY_KEY + uid,HouseTypeVo.build(1, id), System.currentTimeMillis());
        return AjaxResult.success(rentalHourse);
    }

    /**
     * 添加房屋
     * @param insertRentalHourseForm
     * @return
     */
    @Override
    public AjaxResult<Boolean> insertRentalHourse(InsertRentalHourseForm insertRentalHourseForm) {
        RentalHourse rentalHourse = new RentalHourse();
        BeanUtils.copyProperties(insertRentalHourseForm,rentalHourse);
        rentalHourse.setVisitingTime(insertRentalHourseForm.getVisitingTime());
        rentalHourse.setCreateTime(new Date());
        rentalHourse.setUpdateTime(new Date());
        rentalHourse.setIsDelete(0);
        rentalHourse.setState(1);
        rentalHourse.setViewCount(0);
        rentalHourse.setAccusation(0);
        rentalHourse.setLocation(insertRentalHourseForm.getLocation());
        rentalHourse.setLatitude(insertRentalHourseForm.getLatitude());
        rentalHourse.setLongitude(insertRentalHourseForm.getLongitude());
        rentalHourse.setEndTime(new Date(rentalHourse.getEndTime().getTime()+rentalHourse.getTenancyTerm()*24*60*60*1000));
        boolean save = this.save(rentalHourse);
        if (save){
            // 将发布的房屋id存入Redis
            redisTemplate.boundZSetOps(RedisConstant.USER_PUBLISH_KEY + insertRentalHourseForm.getUid()).add(HouseTypeVo.build(1, rentalHourse.getId()), System.currentTimeMillis());
            // 保存位置信息至Redis
            redisTemplate.boundGeoOps(RedisConstant.HOUSE_LOCATION_KEY)
                    .add(new Point(rentalHourse.getLongitude().doubleValue(), rentalHourse.getLatitude().doubleValue()), HouseTypeVo.build(1, rentalHourse.getId()));
        }
        return AjaxResult.success(save);
    }

    /**
     * 获取房东微信
     * @param id 房产id
     * @param uid 房东id
     * @return
     */
    @Override
    public AjaxResult<String> getLandlordWechat(Long id, Long uid) {
        LambdaQueryWrapper<RentalHourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RentalHourse::getId,id);
        wrapper.eq(RentalHourse::getUid,uid);
        RentalHourse rentalHourse = this.getOne(wrapper);
        return AjaxResult.success(rentalHourse.getWechat());
    }

    /**
     * 获取房东手机号
     * @param id 房产id
     * @param uid 房东id
     * @return
     */
    @Override
    public AjaxResult<String> getLandlordPhone(Long id, Long uid) {
        LambdaQueryWrapper<RentalHourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RentalHourse::getId,id);
        wrapper.eq(RentalHourse::getUid,uid);
        RentalHourse rentalHourse = this.getOne(wrapper);
        return AjaxResult.success(rentalHourse.getPhone());
    }

    /**
     * 获取当前用户的所有出租房屋信息
     * @param uid
     * @return
     */
    @Override
    public AjaxResult<List<RentalHourse>> getRentalHourseListByUid(Long uid) {
        LambdaQueryWrapper<RentalHourse> eq = new LambdaQueryWrapper<RentalHourse>().eq(RentalHourse::getUid, uid);
        List<RentalHourse> rentalHourseList = this.list(eq);
        System.out.println(rentalHourseList);
        return AjaxResult.success(rentalHourseList);
    }

    /**
     * 修改出租房屋状态
     * @param id 房产id
     * @param uid 房东id
     * @return
     */
    @Override
    public AjaxResult<Boolean> changeStatus(Long id, Long uid) {
        LambdaQueryWrapper<RentalHourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RentalHourse::getId,id);
        wrapper.eq(RentalHourse::getUid,uid);
        RentalHourse rentalHourse = this.getOne(wrapper);
        if (rentalHourse.getState() == 1){
            rentalHourse.setState(0);
            this.updateById(rentalHourse);
            return AjaxResult.success(true);
        }

        return AjaxResult.success(false);
    }

    /**
     * 收藏房屋
     * @param id 房产id
     * @param uid 用户id，收藏者id
     * @return
     */
    @Override
    public AjaxResult<Boolean> collectHouse(Long id, Long uid) {
        return AjaxResult.success(redisTemplate.boundZSetOps(RedisConstant.USER_COLLECTION_KEY + uid).add(HouseTypeVo.build(1, id), System.currentTimeMillis()));
    }

    /**
     * 取消收藏房屋
     * @param id 房产id
     * @param uid 用户id，收藏者id
     * @return
     */
    @Override
    public AjaxResult<Boolean> cancelCollectHouse(Long id, Long uid) {
        redisTemplate.boundZSetOps(RedisConstant.USER_COLLECTION_KEY + uid).remove(HouseTypeVo.build(1, id));
        return AjaxResult.success(true);
    }

    /**
     * 获取有效出租房屋数
     * @return
     */
    @Override
    public AjaxResult<Long> getValidRentalHourseCount() {
        Long count = this.count(new LambdaQueryWrapper<RentalHourse>().eq(RentalHourse::getState, 0));
        return AjaxResult.success(count);
    }

    /**
     * 获取发布的出租房屋
     * @param id,state
     * @return
     */
    @Override
    public AjaxResult<RentalHourse> getRentalHoursePage(Long id, Integer state) {
        LambdaQueryWrapper<RentalHourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RentalHourse::getId,id);
        wrapper.eq(RentalHourse::getState,state);
        RentalHourse one = this.getOne(wrapper);
        return AjaxResult.success(one);
    }

    @Override
    public AjaxResult<Boolean> accusation(Long id) {
        LambdaQueryWrapper<RentalHourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RentalHourse::getId,id);
        RentalHourse rentalHourse = this.getOne(queryWrapper);
        LambdaUpdateWrapper<RentalHourse> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(RentalHourse::getId,id);
        updateWrapper.set(RentalHourse::getAccusation,rentalHourse.getAccusation()+1);
        return AjaxResult.success(this.update(updateWrapper));
    }
}
